package com.htfyun.fragment.library;

import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;

import com.htfyun.fragment.library.adapter.TreeRecyclerViewAdapter;

import org.geometerplus.android.fbreader.util.AndroidImageSynchronizer;
import org.geometerplus.android.util.UIMessageUtil;
import org.geometerplus.android.util.UIUtil;
import org.geometerplus.fbreader.tree.FBTree;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import me.yokeyword.fragmentation.SupportFragment;

/**
 * Created by sst on 2017/11/1.
 */

public abstract class TreeFragment<T extends FBTree> extends SupportFragment {

    public  AndroidImageSynchronizer ImageSynchronizer;

    private T myCurrentTree;
    // we store the key separately because
    // it will be changed in case of myCurrentTree.removeSelf() call
    private FBTree.Key myCurrentKey;
    private final List<FBTree.Key> myHistory =
            Collections.synchronizedList(new ArrayList<FBTree.Key>());

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ImageSynchronizer = new AndroidImageSynchronizer(getActivity());
    }

    @Override
    public void onDestroy() {

        ImageSynchronizer.clear();
        
        super.onDestroy();
        
    }

    protected abstract T getTreeByKey(FBTree.Key key);
    public abstract TreeRecyclerViewAdapter getTreeAdapter() ;

    public abstract void treeInitOver(T currentTree);


    public Context getContext() {
        return _mActivity;
    }

    protected T getCurrentTree() {
        return myCurrentTree;
    }


    // TODO: change to protected
    public void openTree(final FBTree tree) {
        openTree(tree, true);
    }

    public void clearHistory() {
        getActivity().runOnUiThread(new Runnable() {
            public void run() {
                myHistory.clear();
            }
        });
    }


    public void openTree(final FBTree tree, final boolean storeInHistory) {
        switch (tree.getOpeningStatus()) {
            case WAIT_FOR_OPEN:
            case ALWAYS_RELOAD_BEFORE_OPENING:
                final String messageKey = tree.getOpeningStatusMessage();
                if (messageKey != null) {
                    UIUtil.createExecutor(getActivity(), messageKey).execute(
                            new Runnable() {
                                public void run() {
                                    tree.waitForOpening();
                                }
                            },
                            new Runnable() {
                                public void run() {
                                    openTreeInternal(tree, storeInHistory);
                                }
                            }
                    );
                } else {
                    tree.waitForOpening();
                    openTreeInternal(tree, storeInHistory);
                }
                break;
            default:
                openTreeInternal(tree, storeInHistory);
                break;
        }
    }


    protected void init(FBTree.Key myKey, ArrayList<FBTree.Key> theHistory) {
        final FBTree.Key key = myKey;
        myCurrentTree = getTreeByKey(key);
        // not myCurrentKey = key
        // because key might be null
        myCurrentKey = myCurrentTree.getUniqueKey();
        final TreeRecyclerViewAdapter adapter = getTreeAdapter();
        adapter.replaceAll(myCurrentTree.subtrees());

        myHistory.clear();
        final ArrayList<FBTree.Key> history = theHistory;
        if (history != null) {
            myHistory.addAll(history);
        }

        treeInitOver(myCurrentTree);
    }

    private void openTreeInternal(final FBTree tree, boolean storeInHistory) {
        switch (tree.getOpeningStatus()) {
            case READY_TO_OPEN:
            case ALWAYS_RELOAD_BEFORE_OPENING:
                if (storeInHistory && !myCurrentKey.equals(tree.getUniqueKey())) {
                    myHistory.add(myCurrentKey);
                }
                
                getActivity().runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        init(tree.getUniqueKey(), new ArrayList<FBTree.Key>(myHistory));
                    }
                });
                break;
            case CANNOT_OPEN:
                UIMessageUtil.showErrorMessage(getActivity(), tree.getOpeningStatusMessage());
                break;
        }
    }

    @Override
    public boolean onBackPressedSupport() {
        FBTree parent = null;
        synchronized (myHistory) {
            while (parent == null && !myHistory.isEmpty()) {
                parent = getTreeByKey(myHistory.remove(myHistory.size() - 1));
            }
        }
        if (parent == null && myCurrentTree != null) {
            parent = myCurrentTree.Parent;
        }
        if (parent != null) {
            openTree(parent, false);
            return true;
        }
        
        return super.onBackPressedSupport();
    }
}
